<template>
  <!-- 物料服务BOM弹框 -->
  <base-modal
    :title="title"
    :show.sync="visible"
    width="900px"
    class="material-service-bom-dialog"
  >
    <el-form label-position="top" :model="listQuery" class="search-box" inline @submit.native.prevent>
      <el-form-item :label="productTemplate.length ? `${$t('common.base.product')}：` : ''">
        <el-select
          v-if="productTemplate.length"
          v-model="listQuery.productValue"
          :placeholder="$t('common.base.all')"
          @change="handleChangeProduct"
          clearable
          :style="{width: '200px'}"
        >
          <el-option
            v-for="item in productTemplate"
            :label="item.name"
            :value="item.id"
            :key="item.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-input
          v-model="listQuery.keyword"
          prefix-icon="el-icon-search"
          :placeholder="$t('task.tip.searchTip', {name: ''})"
          @input="handleSearch"
          clearable
          :style="{width: '300px'}"
        ></el-input>
      </el-form-item>
    </el-form>

    <div class="table-box">
      <el-table
        v-loading="listLoading"
        :data="tableData"
        style="width: 100%"
        header-row-class-name="common-list-table-header__v2"
        max-height="500"
        border
        ref="tableRef"
        @select="handleSelectionChange"
        @select-all="handleSelectionChange"
        :row-key="getRowKeys"
      >
        <el-table-column
          type="selection"
          width="55"
          :reserve-selection="true"
        >
        </el-table-column>
        <el-table-column
          v-for="(item, index) in tableColumns"
          :key="`${item.displayName}_${index}`"
          :prop="item.fieldName"
          :label="item.displayName"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <template v-if="item.fieldName === 'salePrice'">
              {{ scope.row | fmt_salePrice_currency }} 
            </template>
            <template v-if="['snManage', 'property'].includes(item.fieldName)">
              {{ $t(`task.${scope.row[item.fieldName]}`) }}
            </template>
            <!-- 状态 -->
            <template v-else-if="item.fieldName === 'materialStatus'">
              {{ scope.row.materialStatus ? $t('common.base.open') : $t('common.base.disable') }}
            </template>

            <template v-else-if="item.formType === 'richtext'">
              <div class='view-detail-btn' @click.stop="openRichtextVisible(scope.row, item)">
                <span v-if="scope.row.attribute[item.fieldName]">{{$t('common.base.view')}}</span>
              </div>
            </template>

            <template v-else>
              {{
                $formatFormField(item, scope.row)
              }}
            </template>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <div class="pagping-box">
      <el-pagination
        class="base-pagination"
        :background="true"
        layout="total, prev, pager, next"
        :total="total"
        :page-size="listQueryPage.pageSize"
        :current-page="listQueryPage.pageNum"
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </div>

    <div slot="footer">
      <el-button @click="visible = false">{{$t('common.base.cancel')}}</el-button>
      <el-button type="primary" @click="handleClickSubmit"
        >{{$t('common.base.save')}}</el-button
      >
    </div>

    <!-- 富文本弹窗 -->
    <base-view-rich-text ref="baseViewRichTextRef"></base-view-rich-text>
  </base-modal>
</template>
<script>
import { MATERIAL_LIST_MAX } from '@src/model/const/Number';
import Platform from '@src/util/platform.ts';
// API
import { getMaterielPage } from '@src/api/ProductV2Api';
import _ from 'lodash';

import { handlerMaterialList } from '@src/modules/task/view/components/materialUtil.js';

export default {
  name: 'material-service-bom-dialog',
  props: {
    columns: {
      type: Array,
      default: [],
    },
    // 质保状态
    warrantyStatus: {
      type: Number,
    },
    warrantyStatusData: {
      type: Array,
      default: () => [],
    },
    // 仓库数据集合
    getWarehouseAggregate: {
      type: Object,
      default: () => ({}),
    },
    productTemplate: {
      type: Array,
      default: () => [],
    },
    // 添加物料弹框的数据
    dataList: {
      type: Array,
      default: () => [],
    }
  },
  data() {
    return {
      visible: false,
      listLoading: false,
      tableData: [],
      total: 0,
      listQuery: {
        productValue: '',
        keyword: '',
        productCatalogId: ''
      },
      listQueryPage: {
        pageNum: 1,
        pageSize: 10,
      },
      multipleSelection: [],
    };
  },
  computed: {
    // 标题
    title() {
      return this.$t('task.edit.chooseMaterial');
    },
    tableColumns() {
      let fields = [
        ...(this.columns || []),
        {
          displayName: this.$t('common.base.quantity'),
          fieldName: 'num',
        },
      ];
      return fields.filter(
        item =>
          item.fieldName != 'warrantyStatus' &&
          item.fieldName != 'total' &&
          item.fieldName != 'action' &&
          item.fieldName != 'preNum' &&
          item.fieldName != 'warehouse' &&
          item.fieldName != 'warehousePosition' &&
          item.fieldName != 'availableNum'
      );
    },
    listIds() {
      return (this.dataList || []).map(item => item.id)
    }
  },
  methods: {
    // 数据处理
    transformData(data) {
      const {
        warehouse,
        warehouseData,
        warehousePosition,
        warehousePositionData,
      } = this.getWarehouseAggregate;
      return data.map(item => {
        return {
          ...item,
          preNum: item.num || 1, // 预计用量的取值： 数量有值就用数量的值，没有就默认1
          sort: item.type,
          serialNumber: item.sn,
          salePrice: item.salePrice || 0,
          warrantyStatus: this.warrantyStatus,
          warrantyStatusData: this.warrantyStatusData,
          warehouse,
          warehouseId: warehouse?.value,
          positionId: warehousePosition?.value,
          warehouseData,
          warehousePosition,
          warehousePositionData,
          availableNum: 0,
        };
      });
    },
    // 获取物料列表数据
    fetchMaterialBill() {
      const params = {
        keyword: this.listQuery.keyword,
        catalogId: this.listQuery.productCatalogId, // 产品类型id
        includeCatalogId: this.listQuery.productCatalogId, // 根据产品搜素对应的物料
        excludeIds: this.listIds, // 过滤数据
        ...this.listQueryPage,
      };

      this.listLoading = true;

      getMaterielPage(params)
        .then(res => {
          const { success, data } = res;
          if (!success) return Platform.toast(res.message, 'error');

          this.tableData = handlerMaterialList(this.transformData(data.list || []), this.tableColumns)

          this.total = data.total || 0;
        })
        .finally(() => {
          this.listLoading = false;
        })
        .catch(err => {
          console.error('err', err);
        });
    },
    // 切换产品
    handleChangeProduct(id) {
      this.listQuery.productCatalogId = this.productTemplate.filter(item => item.id === id)[0]?.catalogId
      this.fetchMaterialBill();
    },
    // 重置数据
    resetList() {
      this.multipleSelection = [];
      this.listQuery.keyword = '';

      this.listQueryPage = {
        pageNum: 1,
        pageSize: 10,
      };

      this.listQuery.productValue = Array.isArray(this.productTemplate) && this.productTemplate[0]?.id;

      this.handleChangeProduct(this.listQuery.productValue)
    },
    // 打开添加弹框
    openMaterialList() {
      if (this.dataList.length >= MATERIAL_LIST_MAX) {
        return this.$message({
          showClose: true,
          message: this.$t('task.tip.addMaterialTip3', {max: MATERIAL_LIST_MAX}),
          type: 'error'
        })
      }

      this.visible = true;
      this.$refs.tableRef.clearSelection();
      this.resetList();
    },
    // 搜索
    handleSearch: _.debounce(function () {
      this.listQueryPage.pageNum = 1;
      this.fetchMaterialBill();
    }, 500),
    // 切换分页
    handleCurrentChange(val) {
      this.listQueryPage.pageNum = val;
      this.fetchMaterialBill();
    },
    getRowKeys(row) {
      return row.id;
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    // 过滤重复的数据
    filterDuplicateData(val) {
      if (!Array.isArray(val)) return;
      
      let map = new Map();
      for (let item of val) {
        if (!map.has(item.id)) {
          map.set(item.id, item);
        }
      }
      return [...map.values()];
    },
    handleClickSubmit() {
      if (!this.multipleSelection.length) {
        return Platform.toast(this.$t('task.tip.applyMaterialTip1'), 'warning')
      }

      let val = [...(this.dataList || []), ...(this.multipleSelection || [])]

      if (val.length > MATERIAL_LIST_MAX) {
        return this.$message({
          showClose: true,
          message: this.$t('task.tip.addMaterialTip3', {max: MATERIAL_LIST_MAX}),
          type: 'error'
        })
      }

      let ret = this.filterDuplicateData(val)
      this.visible = false;
      this.$emit('handleSubmit', ret);
    },
    /** 打开富文本弹窗 */
    openRichtextVisible(row, column) {
      const richtextId = row?.attribute?.[column.fieldName] || ''
      this.$refs?.baseViewRichTextRef?.openDialog(richtextId, false, true);
    }
  },
};
</script>
<style lang="scss" scoped>
.material-service-bom-dialog {
  ::v-deep .base-modal-body {
    padding: 24px;
  }
  .search-box {
    display: flex;
    justify-content: space-between;
    ::v-deep .el-input__inner {
      border: 1px solid #e0e1e2 !important;
    }
    ::v-deep .el-input__inner:focus {
      outline: none;
      border-color: $color-primary-light-6 !important;
    }

    .no_empty {
      padding: 0;
      text-align: center;
      color: #999;
      font-size: 14px;
    }
  }

  .table-box {
    margin-bottom: 10px;
    ::v-deep .el-table {
      border-top: 1px solid #e8e8e8;
      border-left: 1px solid #e8e8e8;
    }
  }

  .base-pagination {
    border: none;
  }
}
</style>